Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

28장. JOIN이 사라진 세계 — 분산 환경에서의 조회

우리는 계속 시스템을 분리해왔다.
서비스가 나뉘고, 데이터베이스도 함께 나뉘었다.

이 변화는 하나의 중요한 결과를 만든다.

더 이상 JOIN을 사용할 수 없다


모놀리스에서는 문제가 아니었다

모놀리스에서는 조회가 단순했다.
하나의 DB 안에 모든 데이터가 있었기 때문이다.

SELECT *
FROM order o
JOIN user u ON o.user_id = u.id
WHERE u.age > 20;

JOIN으로 필요한 데이터를 한 번에 가져오면 끝이었다.


마이크로서비스에서는 달라진다

서비스가 분리되면 데이터도 분리된다.

  • Order DB
  • User DB
  • Payment DB

이 상태에서는 다른 서비스의 DB를 직접 조회할 수 없다.
즉, JOIN이 사라진다.


문제는 조회에서 발생한다

쓰기(Write)는 비교적 단순하다.
각 서비스가 자신의 데이터를 처리하면 된다.

하지만 조회(Query)는 다르다.
화면은 여러 서비스의 데이터를 동시에 요구한다.

  • 주문 + 사용자
  • 주문 + 결제
  • 통계 + 상세

이 시점에서 조회는 쿼리가 아니라 설계 문제가 된다.

분산 시스템에서는 조회도 설계해야 한다


단순한 해결은 통하지 않는다

처음에는 이렇게 생각하기 쉽다.

Order 조회 → User API 호출 → 데이터 조합

하지만 이 방식은 문제가 생긴다.

  • 호출 횟수 증가 (N+1)
  • 응답 속도 저하
  • 장애 전파

결국 규모가 커지면 버틸 수 없다.


해결 전략들

1️⃣ API Composition

여러 서비스를 호출해서 데이터를 조합한다.

장점:

  • 구현이 단순
  • 실시간 데이터

단점:

  • 성능 문제
  • 장애 전파

2️⃣ 데이터 복제 (Denormalization)

다른 서비스 데이터를 일부 복제한다.

예:

  • user_name
  • user_age

장점:

  • 조회 빠름
  • JOIN 불필요

단점:

  • 데이터 정합성
  • 동기화 필요

비정규화는 선택이 아니라 전략이다

3️⃣ 이벤트 기반 조회 모델

이벤트를 받아 조회 전용 데이터를 만든다.

User 이벤트 → Order 조회 데이터 갱신

장점:

  • 복잡한 조회 가능
  • 성능 좋음

단점:

  • 지연 발생
  • 이벤트 처리 필요

→ CQRS Read 모델과 연결된다

Write는 정규화, Read는 비정규화

4️⃣ 검색/인덱스 시스템

데이터를 검색 시스템에 저장한다.

예:

  • Elasticsearch

장점:

  • 강력한 필터링
  • 빠른 조회

단점:

  • 별도 인프라
  • 동기화 필요

어떤 전략을 선택할까

정답은 하나가 아니다.

상황에 따라 선택한다.

  • 단순 조회 → API Composition
  • 빠른 조회 → 데이터 복제
  • 복잡 조회 → CQRS
  • 검색 중심 → 검색 시스템

중요한 오해들

  • API 호출로 JOIN 대체 가능 → ❌
  • 데이터 복제는 나쁜 설계 → ❌
  • 조회는 항상 최신이어야 한다 → ❌

이 장의 핵심

  • JOIN은 사라진다
  • 조회는 설계 문제다
  • API 방식은 한계가 있다
  • 비정규화는 필수 전략이다
  • CQRS는 조회 문제 해결 구조다
  • 상황에 맞게 선택해야 한다